package blockencryption;

import general.Utility;

import javax.crypto.BadPaddingException;

public class BlockCipherer_PrimitiveSolution {

	/**
	 * takes a bunch of data, divides it into blocks, calls Encryptor.cipher()
	 * on each block to en-/decrypt it and merges the blocks together again
	 */
	static int[] blockCipher(byte[] key, int[] lineData, boolean encrypt) throws BadPaddingException {
		// original data
		int[][] dataChunks = Utility.splitData(lineData);
		// manipulated data
		int[][] cipheredDataChunks = new int[dataChunks.length][];

		int[] lastChunk = new int[dataChunks[0].length];
		for (int i = 0; i < dataChunks.length; i++) {
			if (encrypt) {
				cipheredDataChunks[i] = Encryptor.cipher(xor(dataChunks[i], lastChunk), key, encrypt);
				lastChunk = cipheredDataChunks[i];
			} else {
				cipheredDataChunks[i] = xor(Encryptor.cipher(dataChunks[i], key, encrypt), lastChunk);
				lastChunk = dataChunks[i];
			}
		}
		return Utility.mergeData(cipheredDataChunks);
	}

	private static int[] xor(int[] a, int[] b) {
		int[] result;
		int[] shortOne;
		int[] longOne;
		if (a.length >= b.length) {
			shortOne = b;
			longOne = a;
		} else {
			shortOne = a;
			longOne = b;
		}
		result = new int[longOne.length];
		int i = 0;
		for (; i < shortOne.length; i++) {
			result[i] = shortOne[i] ^ longOne[i];
		}
		System.arraycopy(longOne, i, result, i, longOne.length - i);
		return result;
	}
}
